package com.djf.controller;

import com.djf.dto.OrderUserDeliveryDTO;
import com.djf.service.OrderJoinService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 订单关联查询控制器
 * 提供订单、用户、配送表的关联查询接口
 * 演示ShardingJDBC中如何处理跨分片表的关联查询
 *
 * @author djf
 * @since 2025-01-01
 */
@Slf4j
@RestController
@RequestMapping("/api/order-join")
public class OrderJoinController {

    @Autowired
    private OrderJoinService orderJoinService;

    /**
     * 根据订单ID查询订单详情（包含用户和配送信息）
     * 
     * 测试URL: GET /api/order-join/detail/{orderId}
     * 示例: GET /api/order-join/detail/1
     *
     * @param orderId 订单ID
     * @return 订单详情DTO
     */
    @GetMapping("/detail/{orderId}")
    public OrderUserDeliveryDTO getOrderDetail(@PathVariable Long orderId) {
        log.info("查询订单详情接口调用，订单ID: {}", orderId);
        
        try {
            OrderUserDeliveryDTO result = orderJoinService.getOrderDetailById(orderId);
            log.info("订单详情查询成功，订单ID: {}, 结果: {}", orderId, result != null ? "有数据" : "无数据");
            return result;
        } catch (Exception e) {
            log.error("查询订单详情失败，订单ID: {}", orderId, e);
            throw e;
        }
    }

    /**
     * 根据用户ID查询用户的所有订单详情
     * 
     * 测试URL: GET /api/order-join/user/{userId}
     * 示例: GET /api/order-join/user/10001
     *
     * @param userId 用户ID
     * @return 订单详情列表
     */
    @GetMapping("/user/{userId}")
    public List<OrderUserDeliveryDTO> getOrderDetailsByUserId(@PathVariable Long userId) {
        log.info("查询用户订单详情接口调用，用户ID: {}", userId);
        
        try {
            List<OrderUserDeliveryDTO> result = orderJoinService.getOrderDetailsByUserId(userId);
            log.info("用户订单详情查询成功，用户ID: {}, 结果数量: {}", userId, result.size());
            return result;
        } catch (Exception e) {
            log.error("查询用户订单详情失败，用户ID: {}", userId, e);
            throw e;
        }
    }

    /**
     * 根据租户ID和时间范围查询订单详情
     * 
     * 测试URL: GET /api/order-join/tenant/{tenantId}?startTime=2025-01-01T00:00:00&endTime=2025-12-31T23:59:59
     * 示例: GET /api/order-join/tenant/1001?startTime=2025-01-01T00:00:00&endTime=2025-12-31T23:59:59
     *
     * @param tenantId  租户ID
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return 订单详情列表
     */
    @GetMapping("/tenant/{tenantId}")
    public List<OrderUserDeliveryDTO> getOrderDetailsByTenantAndTime(
            @PathVariable Long tenantId,
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") LocalDateTime startTime,
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") LocalDateTime endTime) {
        
        log.info("查询租户订单详情接口调用，租户ID: {}, 时间范围: {} - {}", tenantId, startTime, endTime);
        
        try {
            List<OrderUserDeliveryDTO> result = orderJoinService.getOrderDetailsByTenantAndTime(tenantId, startTime, endTime);
            log.info("租户订单详情查询成功，租户ID: {}, 结果数量: {}", tenantId, result.size());
            return result;
        } catch (Exception e) {
            log.error("查询租户订单详情失败，租户ID: {}, 时间范围: {} - {}", tenantId, startTime, endTime, e);
            throw e;
        }
    }

    /**
     * 根据配送状态查询订单详情
     * 
     * 测试URL: GET /api/order-join/delivery-status/{status}?startTime=2025-01-01T00:00:00&endTime=2025-12-31T23:59:59
     * 示例: GET /api/order-join/delivery-status/2?startTime=2025-01-01T00:00:00&endTime=2025-12-31T23:59:59
     * 配送状态: 1-待配送，2-配送中，3-已送达，4-配送失败
     *
     * @param deliveryStatus 配送状态
     * @param startTime      开始时间
     * @param endTime        结束时间
     * @return 订单详情列表
     */
    @GetMapping("/delivery-status/{deliveryStatus}")
    public List<OrderUserDeliveryDTO> getOrderDetailsByDeliveryStatus(
            @PathVariable Integer deliveryStatus,
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") LocalDateTime startTime,
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") LocalDateTime endTime) {
        
        log.info("根据配送状态查询订单详情接口调用，配送状态: {}, 时间范围: {} - {}", deliveryStatus, startTime, endTime);
        
        try {
            List<OrderUserDeliveryDTO> result = orderJoinService.getOrderDetailsByDeliveryStatus(deliveryStatus, startTime, endTime);
            log.info("配送状态订单详情查询成功，配送状态: {}, 结果数量: {}", deliveryStatus, result.size());
            return result;
        } catch (Exception e) {
            log.error("根据配送状态查询订单详情失败，配送状态: {}, 时间范围: {} - {}", deliveryStatus, startTime, endTime, e);
            throw e;
        }
    }

    /**
     * 根据用户手机号查询订单详情
     * 
     * 测试URL: GET /api/order-join/phone/{phone}
     * 示例: GET /api/order-join/phone/13800138001
     *
     * @param phone 用户手机号
     * @return 订单详情列表
     */
    @GetMapping("/phone/{phone}")
    public List<OrderUserDeliveryDTO> getOrderDetailsByUserPhone(@PathVariable String phone) {
        log.info("根据用户手机号查询订单详情接口调用，手机号: {}", phone);
        
        try {
            List<OrderUserDeliveryDTO> result = orderJoinService.getOrderDetailsByUserPhone(phone);
            log.info("手机号订单详情查询成功，手机号: {}, 结果数量: {}", phone, result.size());
            return result;
        } catch (Exception e) {
            log.error("根据用户手机号查询订单详情失败，手机号: {}", phone, e);
            throw e;
        }
    }

    /**
     * 根据快递单号查询订单详情
     * 
     * 测试URL: GET /api/order-join/tracking/{trackingNumber}
     * 示例: GET /api/order-join/tracking/SF1234567890
     *
     * @param trackingNumber 快递单号
     * @return 订单详情
     */
    @GetMapping("/tracking/{trackingNumber}")
    public OrderUserDeliveryDTO getOrderDetailByTrackingNumber(@PathVariable String trackingNumber) {
        log.info("根据快递单号查询订单详情接口调用，快递单号: {}", trackingNumber);
        
        try {
            OrderUserDeliveryDTO result = orderJoinService.getOrderDetailByTrackingNumber(trackingNumber);
            log.info("快递单号订单详情查询成功，快递单号: {}, 结果: {}", trackingNumber, result != null ? "有数据" : "无数据");
            return result;
        } catch (Exception e) {
            log.error("根据快递单号查询订单详情失败，快递单号: {}", trackingNumber, e);
            throw e;
        }
    }


}